package com.molichuxing.services.infrastructure.service.impl;

import com.molichuxing.framework.dto.Paged;
import com.molichuxing.framework.dto.TabDto;
import com.molichuxing.framework.exception.BizException;
import com.molichuxing.services.infrastructure.bean.ContractBean;
import com.molichuxing.services.infrastructure.convertor.Convert;
import com.molichuxing.services.infrastructure.dao.ContractMapper;
import com.molichuxing.services.infrastructure.dto.request.create.ContractCreateDto;
import com.molichuxing.services.infrastructure.dto.response.ContractDto;
import com.molichuxing.services.infrastructure.service.ContractService;
import com.molichuxing.services.property.ContractStatusEnum;
import com.molichuxing.services.property.ContractTypeEnum;
import com.molichuxing.services.property.DocumentTypeEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.*;

/**
 * <p>
 * 合同表 服务实现类
 * </p>
 *
 * @author zhaopenghui
 * @since 2019-09-11
 */
@Service("contractService")
public class ContractServiceImpl implements ContractService {

    @Autowired
    ContractMapper contractMapper;

    /**
     * 获取合同列表
     *
     * @param map      key:orderCode Long 订单编号
     *                 key:contractCode String 合同编号
     *                 key：startSignedTime LocalDateTime 签订开始日期
     *                 key:endSignedTime LocalDateTime 签订结束日期
     *                 key:startEndTime LocalDateTime 到期开始日期
     *                 key:endEndTime LocalDateTime 到期结束日期
     *                 key:orderCodeList List 合同编号List
     *                 key:contractType Integer 合同类型
     *                 key:mainOrderCode Long 主合同订单号
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public Paged<ContractDto> getContractPage(Map<String, Object> map, Integer pageNum, Integer pageSize) throws Exception {
        long pageCount = contractMapper.getPageCount(map);
        if (pageCount < 1) {
            return null;
        }
        List<ContractBean> contractBeanList = contractMapper.getPage(map, pageNum, pageSize);
        List<ContractDto> contractDtoList = Convert.toContractDtoList(contractBeanList);
        return new Paged<ContractDto>(contractDtoList, pageCount, pageSize);
    }

    /**
     * 子合同列表
     *
     * @param mainOrderCode
     * @return
     * @throws Exception
     */
    @Override
    public List<ContractDto> getSubContractList(Long mainOrderCode) throws Exception {
        List<ContractBean> subList = contractMapper.getSubList(mainOrderCode);
        return Convert.toContractDtoList(subList);
    }

    /**
     * 获取合同/单据信息
     *
     * @param orderCode    订单号
     * @param documentType 文件类型
     * @return
     * @throws Exception
     */
    @Override
    public List<ContractDto> getContractList(Long orderCode, DocumentTypeEnum documentType) throws Exception {
        List<ContractDto> result = null;
        List<Integer> contractTypes = null;
        if (DocumentTypeEnum.SHEET.equals(documentType)) {
            // 取环单据
            contractTypes = Arrays.asList(ContractTypeEnum.MILEAGE_BAG_CAR_CONTRACT.getValue(),
                    ContractTypeEnum.MILEAGE_BAG_RETURN_CAR.getValue(), ContractTypeEnum.MILEAGE_BAG_VALIDATE_CONTRACT.getValue(),
                    ContractTypeEnum.CAR_CONTRACT.getValue(), ContractTypeEnum.EXCLUSIVE_BOOKING_CAR_CONTRACT.getValue());
        } else if (DocumentTypeEnum.CONTRACT.equals(documentType)) {
            // 合同
            contractTypes = Arrays.asList(ContractTypeEnum.MILEAGE_BAG_CONTRACT.getValue(), ContractTypeEnum.MILEAGE_BAG_RENEW_CONTRACT.getValue(),
                    ContractTypeEnum.MILEAGE_BAG_PURCHASED_CONTRACT.getValue(),
                    ContractTypeEnum.COMMON_CONTRACT.getValue(), ContractTypeEnum.SUPPLEMENT_CONTRACT.getValue(),
                    ContractTypeEnum.GUARANTEE_CONTRACT.getValue(), ContractTypeEnum.DEDICATED_CONTRACT.getValue());
        }

        return Convert.toContractDtoList(contractMapper.getContractList(orderCode, contractTypes));
    }

    /**
     * 合同添加
     *
     * @param contractCreateDto
     * @return
     * @throws Exception
     */
    @Override
    public Integer createContract(ContractCreateDto contractCreateDto) throws Exception {
        if (null == contractCreateDto) {
            throw new BizException("合同生成失败");
        }

        ContractBean contractBean = Convert.toContractBean(contractCreateDto);
        contractMapper.create(contractBean);
        return contractBean.getId();
    }

    /**
     * 合同列表
     *
     * @param orderCode
     * @param contractType
     * @return
     */
    @Override
    public List<ContractDto> getContractListByOrderCode(Long orderCode, Integer contractType) {
        List<ContractBean> contractList = contractMapper.getContractListByOrderCode(orderCode, contractType);
        if (null == contractList || contractList.size() < 1) {
            return null;
        }
        List<ContractBean> list = new ArrayList<>();
        ContractBean contractBean = contractList.get(0);
        Long mainOrderCode = contractBean.getMainOrderCode();
        if (mainOrderCode != null) {
            List<ContractBean> contractListByOrderCode = contractMapper.getContractListByOrderCode(mainOrderCode, ContractTypeEnum.MILEAGE_BAG_CONTRACT.getValue());
            if (contractListByOrderCode != null && contractListByOrderCode.size() > 0) {
                for (ContractBean contract : contractListByOrderCode) {
                    list.add(contract);
                }
            }
        }

        for (ContractBean contract : contractList) {
            list.add(contract);
        }
        return Convert.toContractDtoList(list);
    }

    /**
     * 通过合同编号查询
     *
     * @param contractCode
     * @return
     */
    @Override
    public List<ContractDto> getListByContractCode(String contractCode) {
        List<ContractBean> contractList = contractMapper.getListByContractCode(contractCode);
        return Convert.toContractDtoList(contractList);
    }

    /**
     * 合同批量添加
     *
     * @param list
     * @return
     */
    @Override
    public Boolean createContractBatch(List<ContractDto> list) {
        if (null == list || list.size() < 1) {
            return false;
        }

        int result = contractMapper.createContractBatch(list);
        if (result == list.size()) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 获取合同
     *
     * @param id
     * @return
     */
    @Override
    public ContractDto getContractDtoById(Integer id) {
        if (null == id) {
            return null;
        }
        ContractBean contractBean = contractMapper.getById(id);
        return Convert.toContractDto(contractBean);
    }

    /**
     * 修改合同到期日期
     *
     * @param orderCode
     * @param endTime
     * @return
     */
    @Override
    public Boolean modifyContractEndTime(Long orderCode, LocalDate endTime) {
        if (null == orderCode) {
            throw new BizException("合同生成失败");
        }

        if (null == endTime) {
            return false;
        }

        int result = contractMapper.modifyContractEndTime(orderCode, endTime);
        if (result > 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 根据订单号修改状态
     *
     * @param orderCode
     * @param contractStatus
     * @return
     */
    @Override
    public Boolean modifyStatusByOrderCode(Long orderCode, Integer contractStatus) {
        if (null == orderCode || null == contractStatus) {
            throw new BizException("合同状态修改失败");
        }

        int result = contractMapper.modifyStatusByOrderCode(orderCode, contractStatus);
        if (result > 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 根据主订单号修改状态
     *
     * @param mainOrderCode
     * @param contractStatus
     * @return
     */
    @Override
    public Boolean modifyStatusByMainOrderCode(Long mainOrderCode, Integer contractStatus) {
        if (null == mainOrderCode || null == contractStatus) {
            throw new BizException("合同状态修改失败");
        }

        int result = contractMapper.modifyStatusByMainOrderCode(mainOrderCode, contractStatus);
        if (result > 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 合同编号是否存在
     *
     * @param contractCode
     * @return
     */
    @Override
    public Boolean getContractCodeExist(String contractCode) {
        if (null == contractCode) {
            throw new BizException("合同编号为空");
        }

        List<ContractBean> list = contractMapper.getListByContractCode(contractCode);
        if (list.size() > 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 通过订单号查询合同
     *
     * @param orderCode
     * @param contractType
     * @return
     */
    @Override
    public List<ContractDto> getContractByOrderCode(Long orderCode, Integer contractType) {
        if (null == orderCode) {
            throw new BizException("订单号不能为空");
        }

        List<ContractBean> contractList = contractMapper.getContractByOrderCode(orderCode, contractType);
        return Convert.toContractDtoList(contractList);
    }

    /**
     * 通过订单号查询合同
     *
     * @param orderCodeList
     * @param contractType
     * @return
     */
    @Override
    public Map<Long, List<ContractDto>> getContractMapByOrderCode(List<Long> orderCodeList, Integer contractType) {
        if (null == orderCodeList || orderCodeList.size() < 1) {
            throw new BizException("订单号不能为空");
        }

        List<ContractBean> contractList = contractMapper.getContractListByOrderCodeList(orderCodeList, contractType);
        if (null == contractList || contractList.size() < 1) {
            return null;
        }

        Map<Long, List<ContractDto>> map = new HashMap<>();
        for (ContractBean contractBean : contractList) {
            Long orderCode = contractBean.getOrderCode();
            List<ContractDto> contractDtos = map.get(orderCode);
            if (null == contractDtos || contractDtos.size() < 1) {
                contractDtos = new ArrayList<>();
            }
            contractDtos.add(Convert.toContractDto(contractBean));
            map.put(orderCode, contractDtos);
        }
        return map;
    }

    /**
     * 根据状态获取数量
     *
     * @return
     */
    @Override
    public Map<Integer, Integer> getContractCountByStatus() {
        List<TabDto> statusList = contractMapper.getContractCountByStatus();
        if (null == statusList || statusList.size() == 0) {
            return null;
        }

        Map<Integer, Integer> returnMap = new HashMap<Integer, Integer>();
        for (TabDto tabDto : statusList) {
            Integer type = tabDto.getType();
            Integer count = tabDto.getCount();
            returnMap.put(type, count);
        }

        return returnMap;
    }

    /**
     * 修改合同状态
     *
     * @param orderCode        订单号
     * @param contractStatus   修改后状态
     * @param contractTypeList 合同类型list
     * @return
     */
    @Override
    public boolean modifyStatus(Long orderCode, ContractStatusEnum contractStatus,
                                List<ContractTypeEnum> contractTypeList) {
        int rst = 0;
        if (contractTypeList.size() == 1) {
            rst = contractMapper.modifyStatus(orderCode, contractStatus.getValue(), contractTypeList.get(0).getValue());
        } else {
            List<Integer> contractTypeValueList = new ArrayList<>(contractTypeList.size());
            contractTypeList.forEach(contractType -> {
                contractTypeValueList.add(contractType.getValue());
            });
            rst = contractMapper.modifyBatchStatus(orderCode, contractStatus.getValue(),
                    contractTypeValueList);
        }

        return rst > 0;
    }

}
